package com.jeasonzhao.report.engine;

import java.sql.SQLException;
import javax.sql.DataSource;

import com.jeasonzhao.commons.db.Sqlca;
import com.jeasonzhao.commons.db.helper.ConnectionHelper;
import com.jeasonzhao.report.engine.repo.DatabaseConfigurationRepository;
import com.jeasonzhao.report.exceptions.DatabaseException;
import com.jeasonzhao.report.model.ReportDatabaseConfiguration;
import com.jeasonzhao.report.msg.MessageCodes;

public class DatabasePool
{
    private java.util.Hashtable<String,DataSource> m_hashDatabasePool = new java.util.Hashtable<String,DataSource>();
    private static DatabasePool m_instance = new DatabasePool();
    public static DatabasePool getInstance()
    {
        return m_instance;
    }

    private DatabasePool()
    {
    }
    private Sqlca getSqlca(DataSource src)
        throws SQLException
    {
        if(null==src)
        {
        return null;
        }
        else if(src instanceof org.apache.commons.dbcp.BasicDataSource)
        {
            org.apache.commons.dbcp.BasicDataSource ds=(org.apache.commons.dbcp.BasicDataSource)src;
            if(ds.getMaxActive()<=1)
            {
                return new Sqlca(ds.getDriverClassName(),ds.getUrl(),ds.getUsername(),ds.getPassword());
            }
            else
            {
                return new Sqlca(src);
            }
        }
        else
        {
            return new Sqlca(src);
        }
    }
    public Sqlca getSqlca(String databaseId)
        throws DatabaseException
    {
        if(null == databaseId || databaseId.trim().length() < 1)
        {
            throw new DatabaseException.NoIdentifier(null);
        }
        ReportDatabaseConfiguration cfg = null;
        try
        {
            if(m_hashDatabasePool.containsKey(databaseId))
            {
                return getSqlca(m_hashDatabasePool.get(databaseId));
            }
            cfg = DatabaseConfigurationRepository.getInstance().get(databaseId);
            if(null == cfg)
            {
                throw new DatabaseException.WrongIdentifier(databaseId);
            }
            if(cfg.getPoolCapcity() > 0)
            {
                org.apache.commons.dbcp.BasicDataSource ds = new org.apache.commons.dbcp.BasicDataSource();
                ds.setDriverClassName(cfg.getDriver());
                ds.setUrl(cfg.getUrl());
                ds.setUsername(cfg.getUserName());
                ds.setPassword(cfg.getPassword());
                ds.setMaxActive(Math.max(cfg.getPoolCapcity(),1));
                ds.setInitialSize(Math.max(cfg.getPoolActive(),1));
                m_hashDatabasePool.put(databaseId,ds);
                Configuration.getInstance().getLogger().info(MessageCodes.format(MessageCodes.CFG_DB_CREATE_A_NEW_POOL,cfg.getDatabaseName(),cfg.getDriver(),cfg.getUrl()));
                return getSqlca(ds);
            }
            else
            {
                return new Sqlca(ConnectionHelper.connect(cfg.getDriver(),cfg.getUrl(),cfg.getUserName(),cfg.getPassword()));
            }
        }
        catch(SQLException ex)
        {
            throw new DatabaseException.ConnectFail(cfg,ex);
        }
    }
}
